package com.yanfei.zero.application.handler.lock;

import java.util.concurrent.TimeUnit;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
@Aspect
@Component
@Order(2)
public class LockAOP  {
	
	@Autowired
	private RedissonClient redissonClient;
	@Pointcut("@annotation(AddLock)")
	public void addLock() {}

	@Around("addLock()")
	public Object addLock(ProceedingJoinPoint joinPoint) throws Throwable {
		
        MethodSignature ms = (MethodSignature)joinPoint.getSignature();
        
        AddLock needLock = ms.getMethod().getAnnotation(AddLock.class);
        
        String lockName = needLock.value();
		// Get method arguments
		Object[] args = joinPoint.getArgs();
		
		Object result =null;
		
		RLock lock = redissonClient.getLock(lockName);
		try {
			// 尝试获取锁，参数分别是: 获取锁的最大等待时间(期间会重试)，锁自动释放时间，时间单位
			boolean isLocked = lock.tryLock(100, 10, TimeUnit.SECONDS);
			if (isLocked) {
				// execute your critical section here
				 result = joinPoint.proceed(args);

			} else {
				// handle the case where the lock was not acquired
				
			}
		} catch (InterruptedException e) {
			// handle the case where the thread was interrupted while waiting for the lock
		} finally {
			lock.unlock();
		}
		return result;
		
	
		
	}

}
